using System;
using System.Collections.Generic;
using System.Text;

namespace PicAFlick.Domain
{
    public class ImageDetails
    {
        private string _fileName;

        public string FileName
        {
            get { return _fileName; }
            set { _fileName = value; }
        }
        private ImageType _imageType;
        private Folder _primaryFolder;

        public Folder PrimaryFolder
        {
            get { return _primaryFolder; }
            set { _primaryFolder = value; }
        }

        public ImageType ImageType
        {
            get
            {
                return _imageType;

            }
            set
            {
                _imageType = value;
            }
        }

        internal static ImageDetails ImportImage(System.IO.FileInfo fi)
        {
            ImageDetails retVal = new ImageDetails();
            retVal.FileName = fi.Name;
            retVal.Created = fi.CreationTime;
            retVal.Amended = fi.LastWriteTime;
            retVal.FileSize = fi.Length;
            return retVal;
        }

        private DateTime _created;

        public DateTime Created
        {
            get { return _created; }
            set { _created = value; }
        }
        private DateTime _amended;

        public DateTime Amended
        {
            get { return _amended; }
            set { _amended = value; }
        }
        private long _fileSize;

        public long FileSize
        {
            get { return _fileSize; }
            set { _fileSize = value; }
        }
        private System.Drawing.Image _fullImage;

        public System.Drawing.Image FullImage
        {
            get { return _fullImage; }
            set { _fullImage = value; }
        }
        public void LoadImage()
        {
            iImageCount++;
            System.IO.Stream filestream = null;
            try
            {
                filestream = this.PrimaryFolder.GetImageStream(this.FileName);
                _fullImage = System.Drawing.Image.FromStream(filestream);
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
                throw;
            }
            finally
            {
                if (filestream != null)
                {
                    filestream.Close();
                }
            }


        }
        public static int iImageCount = 0;


        public bool FullImageLoaded
        {
            get
            {
                return _fullImage != null;
            }
        }
        private System.Drawing.Image _thumbnail;

        public System.Drawing.Image Thumbnail
        {
            get
            {
                if (_thumbnail == null)
                {
                    //Heck - we havn't got a thumbnail - lets give a default and then set about building one in the background!
                    _thumbnail = UnknownImageThumbnail;
                    //then background worker to build

                    System.ComponentModel.BackgroundWorker bg = new System.ComponentModel.BackgroundWorker();
                    bg.DoWork += new System.ComponentModel.DoWorkEventHandler(thumbnailCreationWorker_doWork);
                    bg.RunWorkerAsync();
                    //MakeThumbnail();
                    
                }
                return _thumbnail;
            }
        }

        private static int ThumbCount = 0;
        private static object ThumbCountLock = new object();
        void thumbnailCreationWorker_doWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            while (ThumbCount > 5)
            {
                //only process 5 images at a time
                System.Threading.Thread.Sleep(20);
            }
            lock (ThumbCountLock)
            {
                ThumbCount++;
            }
            this.MakeThumbnail();
            lock (ThumbCountLock)
            {
                ThumbCount--;
            }
        }


        public delegate void ThumbnailUpdatedHandler(object sender, EventArgs e);
        public event ThumbnailUpdatedHandler OnThumbnailUpdated;


        public void MakeThumbnail()
        {
            bool requireUnload = false;
            if (!FullImageLoaded)
            {
                LoadImage();
                requireUnload = true;
            }
            _thumbnail = new System.Drawing.Bitmap(_fullImage, new System.Drawing.Size(100, 100));



            if (requireUnload)
            {
                UnloadImage();
            }

            //raise an event to indicate that the thumbnail has been updated
            if (OnThumbnailUpdated != null)
            {
                OnThumbnailUpdated(this, new EventArgs());
            }

        }

        public void UnloadImage()
        {
            _fullImage.Dispose();
            _fullImage = null;
        }


        public static System.Drawing.Image _unknownImageThumbnail;
        public static Object _unknownImageThumbnailLock = new object();

        public System.Drawing.Image UnknownImageThumbnail
        {
            get
            {
                lock (_unknownImageThumbnailLock)
                {
                    if (_unknownImageThumbnail == null)
                    {
                        //load from internal resource
                        System.IO.Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("PicAFlick.Domain.UnknownThumb.png");
                        _unknownImageThumbnail = System.Drawing.Image.FromStream(s);
                    }
                }
                return _unknownImageThumbnail;
            }
        }

        private VirtualImage _virtualImage;

        public VirtualImage VirtualImage
        {
            get
            {
                if (_virtualImage == null)
                {
                    bool requireUnload = false;
                    if (!FullImageLoaded)
                    {
                        LoadImage();
                        requireUnload = true;
                    }

                    _virtualImage = new VirtualImage((System.Drawing.Image)_fullImage.Clone());


                    if (requireUnload)
                    {
                        UnloadImage();
                    }
                }
                return _virtualImage;
            }
        }
    }
}
